/*
 * HttpHandleCoding.h
 *
 *  Created on: May 2, 2009
 *      Author: kuncai
 */

#ifndef HTTPHANDLECODING_H_
#define HTTPHANDLECODING_H_

#include "httphandle.h"
#include "codeutil.h"
#include "resource.h"
#include "buffer.h"
using namespace Http;

#define NOACCEPTED -1 
#define IDENTITY 0 
#define GZIP 1
#define DEFLATE 2  

class HttpHandleCoding :public HttpHandle{
	private:
		int IsAccept(const char* cEncoding, map<string,float>* qList){
			map<string,float>::iterator iter;
			iter = qList->find(cEncoding);
			float q=0;
			if(iter != qList->end()){
				q = iter->second;
				if(q > 0){
					//gzip coding
					return 0;
				}
			}
			return -1;
		}
	public:
		void ProcessRequest(HttpRequest* httpRequest, HttpResponse* httpResponse){
			string contentCoding = "";
			int codingtype = IDENTITY;
			contentCoding = httpRequest->GetHeader(Http::AcceptEncoding);
			if(contentCoding != ""){
				map<string,float>* qList = new map<string,float>();
				int res = httpRequest->HttpSpilt_q(contentCoding, qList);
				if(IsAccept(Http::Deflate, qList)==0){
					codingtype = DEFLATE; 
				}else if(IsAccept(Http::Any, qList)!=0){
					codingtype = NOACCEPTED;
				}
				delete qList;
			}
			if(codingtype != NOACCEPTED){
				//get file content
				Buffer* ptBufferIndex = httpResponse->GetContent();
				if(ptBufferIndex->GetLimit() == 0){
					string filepath = httpRequest->GetParam("url"); 
					ResourceItem* ptResourceItem = Resource::GetResource(filepath.c_str());
					ptBufferIndex = ptResourceItem->GetBuffer();
				}
				//end get file content

				Buffer bContentEncoding; 
				if(ptBufferIndex != NULL && ptBufferIndex->GetLimit()!=0){
					switch(codingtype){
						case DEFLATE:
							if(CodeUtil::EnCodingDeflate(*ptBufferIndex, &bContentEncoding) == 0){
								//deflate encoding success
								httpResponse->SetHeader(Http::ContentEncoding,Http::Deflate);
							}else{
								bContentEncoding = *ptBufferIndex;
							}
							break;
						case IDENTITY:
							bContentEncoding = *ptBufferIndex;
							break;
					}
				}else{
					bContentEncoding = *ptBufferIndex;
				}

				httpResponse->SetContent(&bContentEncoding);
				httpResponse->SetStatus("200");
				httpResponse->SetReason("OK");
				if(successor != NULL){
					successor->ProcessRequest(httpRequest, httpResponse);
				}
			}else{
				httpResponse->SetStatus("406");
				httpResponse->SetReason("Not Acceptable");
				if(error != NULL){
					error->ProcessRequest(httpRequest, httpResponse);
				}
			}
		}
};

#endif /* HTTPHANDLECODING_H_ */

